/*******************************************
 * whiteboard.cpp                          *
 * Written by Brandon Lee and Jacob Talley *
 * Date: 4/15/2011                         *
 *******************************************/

#include "WProgram.h"
#include "whiteboard.h"
#include "alphabet.h"

Whiteboard::Whiteboard(int data, int clk, int latch, int notOutputEnable, int demuxA, int demuxB, int demuxC){ //Constructor
  //Sets pins to be used for communication with whiteboard
  pinMode(data, OUTPUT);
  pinMode(clk, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(notOutputEnable, OUTPUT);
  pinMode(demuxA, OUTPUT);
  pinMode(demuxB, OUTPUT);
  pinMode(demuxC, OUTPUT);
  
  //Initializing variables for pins
  _dataPin = data;
  _clockPin = clk;
  _latchPin = latch;
  _notOEPin = notOutputEnable;
  _demuxAPin = demuxA;
  _demuxBPin = demuxB;
  _demuxCPin = demuxC;
  
  //Initializing the board matrix to zeros
  resetScreen();
}


void Whiteboard::resetScreen(){         //This method sets all LEDs on the whiteboard to off
  for(int row = 0; row < 8; row++){
    for(int col = 0; col < 32; col++){  //Sets the boardMatrix to a blank screen
      boardMatrix[row][col] = false;
    }
  }
}


void Whiteboard::dispScreen(){
  for(int row = 0; row < 8; row++){
    digitalWrite(_notOEPin, HIGH);     //Enables the !Output Enable pin. This results in the output being not enabled, or disabled.
    digitalWrite(_latchPin, HIGH);     //Enables the Latch pin. This allows the LEDs to be set.
    
    switch(row){                       //Selects the row
     case 0:
      digitalWrite(_demuxAPin, LOW);
      digitalWrite(_demuxBPin, LOW);
      digitalWrite(_demuxCPin, LOW);
      break;
     case 1:
      digitalWrite(_demuxCPin, HIGH);
      break;
     case 2:
      digitalWrite(_demuxBPin, HIGH);
      digitalWrite(_demuxCPin, LOW);
      break;
     case 3:
      digitalWrite(_demuxCPin, HIGH);
      break;
     case 4:
      digitalWrite(_demuxAPin, HIGH);
      digitalWrite(_demuxBPin, LOW);
      digitalWrite(_demuxCPin, LOW);
      break;
     case 5:
      digitalWrite(_demuxCPin, HIGH);
      break;
     case 6:
      digitalWrite(_demuxBPin, HIGH);
      digitalWrite(_demuxCPin, LOW);
      break;
     case 7:
      digitalWrite(_demuxCPin, HIGH);
      break;
    }
    
    for(int col = 31; col >= 0; col--){   //Selects the column
      if(boardMatrix[row][col] == true){  //If the boardMatrix at the selected coordinates is set to "true"
        digitalWrite(_dataPin, HIGH);     //Turn the corresponding LED on
      }else{
        digitalWrite(_dataPin, LOW);      //Otherwise, turn the corresponding LED off
      }
      digitalWrite(_clockPin, HIGH);      //Cycle the clock once
      digitalWrite(_clockPin, LOW);
      digitalWrite(_dataPin, LOW);        //Default the next LED to "off"
    }
    digitalWrite(_latchPin, LOW);         //Disable LED setting ability
    digitalWrite(_notOEPin, LOW);         //Display output
    delay(1);
  }
}

void Whiteboard::delayScreen(unsigned long int milliSecs){
  unsigned long int endTime = millis() + milliSecs;    //Set the endtime
  while(endTime > millis()){                           //Loop until endtime is reached
    dispScreen();                                      //Run dispScreen
  }
}

void Whiteboard::changeSinglePin(int rowCoords, int colCoords, boolean value){
  boardMatrix[rowCoords][colCoords] = value;           //Change LED  at (rowCoords, colCoords) to "value"
}

boolean Whiteboard::isLit(int rowCords, int colCords){
  return boardMatrix[rowCords][colCords];              //Return value at (rowCoords, colCoords) of boardMatrix
}

/*void Whiteboard::stringDisp(){
  for(int row = 0; row < 5; row++){
    for(int col = 0; col < 4; col++){
      boardMatrix[row+2][26-col] = aMatrix[row][col];
      delayScreen(250);
    }
  }
}*/

void Whiteboard::charDisp(char letter){
  for(int col = 0; col < 5; col++){
    for(int row = 0; row < 5; row++){
      for(int moveCol = 0; moveCol < 26; moveCol++){
        boardMatrix[row+2][moveCol] = boardMatrix[row+2][moveCol+1]; //Move each column one LED to the left, resulting in a scrolling effect
      }
      switch(letter){                                                //Select letter to display
        case 'A':
        case 'a':
        boardMatrix[row+2][26] = aMatrix[row][col];
        break;
        case 'B':
        case 'b':
        boardMatrix[row+2][26] = bMatrix[row][col];
        break;
        case 'C':
        case 'c':
        boardMatrix[row+2][26] = cMatrix[row][col];
        break;
        case 'D':
        case 'd':
        boardMatrix[row+2][26] = dMatrix[row][col];
        break;
        case 'E':
        case 'e':
        boardMatrix[row+2][26] = eMatrix[row][col];
        break;
        case 'F':
        case 'f':
        boardMatrix[row+2][26] = fMatrix[row][col];
        break;
        case 'G':
        case 'g':
        boardMatrix[row+2][26] = gMatrix[row][col];
        break;
        case 'H':
        case 'h':
        boardMatrix[row+2][26] = hMatrix[row][col];
        break;
        case 'I':
        case 'i':
        boardMatrix[row+2][26] = iMatrix[row][col];
        break;
        case 'J':
        case 'j':
        boardMatrix[row+2][26] = jMatrix[row][col];
        break;
        case 'K':
        case 'k':
        boardMatrix[row+2][26] = kMatrix[row][col];
        break;
        case 'L':
        case 'l':
        boardMatrix[row+2][26] = lMatrix[row][col];
        break;
        case 'M':
        case 'm':
        boardMatrix[row+2][26] = mMatrix[row][col];
        break;
        case 'N':
        case 'n':
        boardMatrix[row+2][26] = nMatrix[row][col];
        break;
        case 'O':
        case 'o':
        boardMatrix[row+2][26] = oMatrix[row][col];
        break;
        case 'P':
        case 'p':
        boardMatrix[row+2][26] = pMatrix[row][col];
        break;
        case 'Q':
        case 'q':
        boardMatrix[row+2][26] = qMatrix[row][col];
        break;
        case 'R':
        case 'r':
        boardMatrix[row+2][26] = rMatrix[row][col];
        break;
        case 'S':
        case 's':
        boardMatrix[row+2][26] = sMatrix[row][col];
        break;
        case 'T':
        case 't':
        boardMatrix[row+2][26] = tMatrix[row][col];
        break;
        case 'U':
        case 'u':
        boardMatrix[row+2][26] = uMatrix[row][col];
        break;
        case 'V':
        case 'v':
        boardMatrix[row+2][26] = vMatrix[row][col];
        break;
        case 'W':
        case 'w':
        boardMatrix[row+2][26] = wMatrix[row][col];
        break;
        case 'X':
        case 'x':
        boardMatrix[row+2][26] = xMatrix[row][col];
        break;
        case 'Y':
        case 'y':
        boardMatrix[row+2][26] = yMatrix[row][col];
        break;
        case 'Z':
        case 'z':
        boardMatrix[row+2][26] = zMatrix[row][col];
        break;
        case '0':
        boardMatrix[row+2][26] = zeroMatrix[row][col];
        break;
        case '1':
        boardMatrix[row+2][26] = oneMatrix[row][col];
        break;
        case '2':
        boardMatrix[row+2][26] = twoMatrix[row][col];
        break;
        case '3':
        boardMatrix[row+2][26] = threeMatrix[row][col];
        break;
        case '4':
        boardMatrix[row+2][26] = fourMatrix[row][col];
        break;
        case '5':
        boardMatrix[row+2][26] = fiveMatrix[row][col];
        break;
        case '6':
        boardMatrix[row+2][26] = sixMatrix[row][col];
        break;
        case '7':
        boardMatrix[row+2][26] = sevenMatrix[row][col];
        break;
        case '8':
        boardMatrix[row+2][26] = eightMatrix[row][col];
        break;
        case '9':
        boardMatrix[row+2][26] = nineMatrix[row][col];
        break;
        case ' ':
        boardMatrix[row+2][26] = spaceMatrix[row][col];
        break;
      }
    }
    delayScreen(400);
  }
}

void Whiteboard::stringDisp(char string[], int length){
  for(int i = 0; i < length; i++){
    charDisp(string[i]);
  }
}
